﻿using System;
using System.Collections.Generic;

namespace BlueLotus7.Common
{
    /// <summary>
    /// A common utility for data caching.
    /// </summary>
    public class CacheUtility
    {
        object locker = new object();
        Dictionary<string, CacheItem> cacheItems = new Dictionary<string, CacheItem>();

        private static CacheUtility instance = new CacheUtility();
        public static CacheUtility Instance
        {
            get
            {
                return instance;
            }
        }
        private CacheUtility() { }

        /// <summary>
        /// Gets cache item by identity.
        /// </summary>
        /// <param name="identity">The identity</param>
        /// <returns>The <c>CacheItem</c> instance.</returns>
        public CacheItem GetCacheItem(string identity)
        {
            if (string.IsNullOrWhiteSpace(identity))
            {
                throw new ArgumentException("identity");
            }

            CacheItem cacheItem = null;

            lock (locker)
            {
                if (cacheItems.ContainsKey(identity))
                {
                    cacheItem = cacheItems[identity];
                }
            }

            return cacheItem;
        }

        /// <summary>
        /// Updates cache item.
        /// </summary>
        /// <param name="identity">The identity.</param>
        /// <param name="cacheObject">The object to cache.</param>
        /// <param name="expiredStamp">The expired date time.</param>
        public void UpdateCacheItem(string identity, object cacheObject, DateTime? expiredStamp)
        {
            if (string.IsNullOrWhiteSpace(identity))
            {
                throw new ArgumentException("identity");
            }

            lock (locker)
            {
                if (cacheItems.ContainsKey(identity))
                {
                    CacheItem cacheItem = cacheItems[identity];
                    cacheItem.Update(cacheObject, expiredStamp);
                }
                else
                {
                    CacheItem cacheItem = new CacheItem();
                    cacheItem.Update(cacheObject, expiredStamp);
                    cacheItems.Add(identity, cacheItem);
                }
            }
        }

        /// <summary>
        /// Updates cache item.
        /// </summary>
        /// <param name="identity">The identity.</param>
        /// <param name="cacheObject">The object to cache.</param>
        public void UpdateCacheItem(string identity, object cacheObject)
        {
            UpdateCacheItem(identity, cacheObject, null);
        }

        /// <summary>
        /// Sets cache item expired.
        /// </summary>
        /// <param name="identity">The identity.</param>
        public void SetExpired(string identity)
        {
            if (string.IsNullOrWhiteSpace(identity))
            {
                throw new ArgumentException("identity");
            }

            lock (locker)
            {
                if (cacheItems.ContainsKey(identity))
                {
                    CacheItem cacheItem = cacheItems[identity];
                    cacheItem.NeedRefresh = true;
                }
            }
        }
    }
}